Next: Signals, Previous: Asynchronous Methods, Up: Top [Contents][Index]
In order to register methods on the D-Bus, Emacs has to request a well known name on the D-Bus under which it will be available for other clients. Names on the D-Bus can be registered and unregistered using the following functions:
Register the known name service on D-Bus bus.
bus is either the symbol :system
or the symbol :session.
service is the service name to be registered on the D-Bus. It must be a known name.
flags is a subset of the following keywords:
:allow-replacement: Allow another service
to become the primary owner if requested.:replace-existing: Request to replace the
current primary owner.:do-not-queue: If we can not become the
primary owner do not place us in the queue.One of the following keywords is returned:
:primary-owner: We have become the primary
owner of the name service.:in-queue: We could not become the primary
owner and have been placed in the queue.:exists: We already are in the queue.:already-owner: We already are the primary
owner.Unregister all objects from D-Bus bus, registered by Emacs for service.
bus is either the symbol :system
or the symbol :session.
service is the D-Bus service name of the D-Bus. It must be a known name. Emacs releases its association to service from D-Bus.
One of the following keywords is returned:
:released: We successfully released the
name service.:non-existent: The name service
does not exist on the bus.:not-owner: We are not an owner of the
name service.When a name has been chosen, Emacs can offer own methods, which can be called by other applications. These methods could be an implementation of an interface of a well known service, like ‘org.freedesktop.TextEditor’.
It could be also an implementation of an own interface. In
this case, the service name must be
‘org.gnu.Emacs’. The object path shall
begin with
‘/org/gnu/Emacs/Application’,
and the interface name shall be
org.gnu.Emacs.Application.
‘Application’ is the
name of the application which provides the interface.
The well known service name ‘org.gnu.Emacs’ of Emacs.
The object path namespace ‘/org/gnu/Emacs’ used by Emacs.
The interface namespace org.gnu.Emacs used by
Emacs.
With this function, an application registers method on the D-Bus bus.
bus is either the symbol :system
or the symbol :session.
service is the D-Bus service name of the D-Bus object method is registered for. It must be a known name (See discussion of dont-register-service below).
path is the D-Bus object path service is registered (See discussion of dont-register-service below).
interface is the interface offered by service. It must provide method.
handler is a Lisp function to be called when a method call is received. It must accept as arguments the input arguments of method. handler should return a list, whose elements are to be used as arguments for the reply message of method. This list can be composed like the input parameters in Type Conversion.
If handler wants to return just one Lisp object and it is not a cons cell, handler can return this object directly, instead of returning a list containing the object.
In case handler shall return a reply message
with an empty argument list, handler must return
the symbol :ignore.
When dont-register-service is
non-nil, the known name service is
not registered. This means that other D-Bus clients have no
way of noticing the newly registered method. When interfaces
are constructed incrementally by adding single methods or
properties at a time, dont-register-service can be
used to prevent other clients from discovering the still
incomplete interface.
The default D-Bus timeout when waiting for a message reply is 25 seconds. This value could be even smaller, depending on the calling client. Therefore, handler shall not last longer than absolutely necessary.
dbus-register-method returns a Lisp object,
which can be used as argument in
dbus-unregister-object for removing the
registration for method. Example:
(defun my-dbus-method-handler (filename)
(let (result)
(if (find-file filename)
(setq result '(:boolean t))
(setq result '(:boolean nil)))
result))
⇒ my-dbus-method-handler
(dbus-register-method
:session "org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"
"org.freedesktop.TextEditor" "OpenFile"
'my-dbus-method-handler)
⇒ ((:method :session "org.freedesktop.TextEditor" "OpenFile")
("org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"
my-dbus-method-handler))
If you invoke the method
‘org.freedesktop.TextEditor.OpenFile’
from another D-Bus application with a filename as parameter,
the file is opened in Emacs, and the method returns either
true or false, indicating the success
of the method. As test tool one could use the command line
tool dbus-send in a shell:
# dbus-send --session --print-reply \
--dest="org.freedesktop.TextEditor" \
"/org/freedesktop/TextEditor" \
"org.freedesktop.TextEditor.OpenFile" string:"/etc/hosts"
-| method return sender=:1.22 -> dest=:1.23 reply_serial=2
boolean true
You can indicate an error by raising the Emacs signal
dbus-error. The handler above could be changed
like this:
(defun my-dbus-method-handler (&rest args)
(unless (and (= (length args) 1) (stringp (car args)))
(signal 'dbus-error (list (format "Wrong argument list: %S" args))))
(condition-case err
(find-file (car args))
(error (signal 'dbus-error (cdr err))))
t)
⇒ my-dbus-method-handler
The test runs then
# dbus-send --session --print-reply \
--dest="org.freedesktop.TextEditor" \
"/org/freedesktop/TextEditor" \
"org.freedesktop.TextEditor.OpenFile" \
string:"/etc/hosts" string:"/etc/passwd"
-| Error org.freedesktop.DBus.Error.Failed:
Wrong argument list: ("/etc/hosts" "/etc/passwd")
With this function, an application declares a property on the D-Bus bus.
bus is either the symbol :system
or the symbol :session.
service is the D-Bus service name of the D-Bus. It must be a known name.
path is the D-Bus object path service is registered (See discussion of dont-register-service below).
interface is the name of the interface used at path, property is the name of the property of interface.
access indicates, whether the property can be
changed by other services via D-Bus. It must be either the
symbol :read or :readwrite.
value is the initial value of the property, it can
be of any valid type (see dbus-call-method for
details).
If property already exists on path,
it will be overwritten. For properties with access type
:read this is the only way to change their
values. Properties with access type :readwrite
can be changed by dbus-set-property.
The interface
‘org.freedesktop.DBus.Properties’ is
added to path, including a default handler for the
‘Get’,
‘GetAll’ and
‘Set’ methods of this interface.
When emits-signal is non-nil, the
signal ‘PropertiesChanged’ is sent
when the property is changed by
dbus-set-property.
When dont-register-service is
non-nil, the known name service is
not registered. This means that other D-Bus clients have no
way of noticing the newly registered method. When interfaces
are constructed incrementally by adding single methods or
properties at a time, dont-register-service can be
used to prevent other clients from discovering the still
incomplete interface.
Example:
(dbus-register-property
:session "org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"
"org.freedesktop.TextEditor" "name" :read "GNU Emacs")
⇒ ((:property :session "org.freedesktop.TextEditor" "name")
("org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"))
(dbus-register-property
:session "org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"
"org.freedesktop.TextEditor" "version" :readwrite emacs-version t)
⇒ ((:property :session "org.freedesktop.TextEditor" "version")
("org.freedesktop.TextEditor" "/org/freedesktop/TextEditor"))
Other D-Bus applications can read the property via the
default methods
‘org.freedesktop.DBus.Properties.Get’
and
‘org.freedesktop.DBus.Properties.GetAll’.
Testing is also possible via the command line tool
dbus-send in a shell:
# dbus-send --session --print-reply \
--dest="org.freedesktop.TextEditor" \
"/org/freedesktop/TextEditor" \
"org.freedesktop.DBus.Properties.GetAll" \
string:"org.freedesktop.TextEditor"
-| method return sender=:1.22 -> dest=:1.23 reply_serial=3
array [
dict entry(
string "name"
variant string "GNU Emacs"
)
dict entry(
string "version"
variant string "23.1.50.5"
)
]
It is also possible, to apply the
dbus-get-property,
dbus-get-all-properties and
dbus-set-property functions (see Properties
and Annotations).
(dbus-set-property :session "org.freedesktop.TextEditor" "/org/freedesktop/TextEditor" "org.freedesktop.TextEditor" "version" "23.1.50") ⇒ "23.1.50" (dbus-get-property :session "org.freedesktop.TextEditor" "/org/freedesktop/TextEditor" "org.freedesktop.TextEditor" "version") ⇒ "23.1.50"
Unregister object from the D-Bus.
object must be the result of a preceding
dbus-register-method,
dbus-register-property or
dbus-register-signal call (see Signals). It returns
t if object has been unregistered,
nil otherwise.
When object identifies the last method or property, which is registered for the respective service, Emacs releases its association to the service from D-Bus.
Next: Signals, Previous: Asynchronous Methods, Up: Top [Contents][Index]